<?php
namespace WDB\Query\Element;
use WDB,
    WDB\Exception;

/**
 * Database column identifier. May be fully qualified (schema.table.column), table-level qualified (table.column)
 * or simple name (column only)
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 *
 * @property string $schema
 * @property string $table
 * @property string $column
 */
class ColumnIdentifier extends WDB\Structure\Structure implements iExpression
{
    const ALL_COLUMNS = TRUE;
    /**
     * Factory method creating column identifier from string in form of schema.table.column.
     *
     *
     * @param string|ColumnIdentifier dot-separated name or already a column identifier
     * @return ColumnIdentifier
     */
    public static function parse($str)
    {
        if ($str instanceof ColumnIdentifier) return $str;

        $ids = array_reverse(explode('.', $str));
        foreach ($ids as &$id)
        {
            $id = WDB\GTO\WsqlLanguage::unquoteIdentifier($id);
        } unset($id);
        return new self(array('column'=>$ids[0], 'table'=>count($ids)>1?$ids[1]:NULL, 'schema'=>count($ids)>2?$ids[2]:NULL));
    }

    /**
     * Creates column identifier from identifier parts.
     *
     * @param string|TRUE column name or TRUE for all columns (*)
     * @param string|NULL table name
     * @param string|NULL schema name
     * @return ColumnIdentifier
     */
    public static function create($column, $table = NULL, $schema = NULL)
    {
        if (!is_string($column) && $column !== TRUE) throw new Exception\BadArgument('Column name must be a string or TRUE, '.gettype($column).' given.');
        if (!is_string($table) && !is_null($table)) throw new Exception\BadArgument('Table name must be a string.');
        if (!is_string($schema) && !is_null($schema)) throw new Exception\BadArgument('Schema name must be a string.');
        return new self(array('column'=>$column, 'table'=>$table, 'schema'=>$schema));
    }

    //when looking for direct constructor calls
    //public function __construct($x, $a = NULL)
    //{
    //    if ($x === TRUE) parent::__construct($a); else throw new Exception\WDBException('direct constructor');
    //}

    private static $allColumns = NULL;

    public static function allColumns()
    {
        if (self::$allColumns === NULL)
        {
            self::$allColumns = self::create(self::ALL_COLUMNS);
        }
        return self::$allColumns;
    }

    public function toSQL(WDB\SQLDriver\iSQLDriver $driver)
    {
        return $driver->tosql_column($this);
    }
}
